#include "Building.h"
#include "RandomNumberGenerator.h"
#include "DXUT/DXUT.h"

#define _USE_MATH_DEFINES
#include <math.h>

void Building::Generate(D3DXVECTOR3 centre,D3DXVECTOR3* corners,float height)
{
	m_vPos=centre;
	int max_height = height;
	m_Height = (MY_RAND(max_height/2)+1)+(max_height/2);

	D3DXCreatePolygon(TheD3DApp::Instance()->GetD3DDev(),1,10,&m_pMesh,0);

	HRESULT hr;
	//V(m_pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT ,0,0,0,0));
	//V(D3DXComputeNormals(m_pMesh,0));

}
void Building::Generate(D3DXVECTOR3 offset, Triangle area, float MaxHeight)
{
	D3DXVECTOR3 a=area.a;
	D3DXVECTOR3 b=area.b;
	D3DXVECTOR3 c=area.c;
	m_vCentroid = D3DXVECTOR3((a.x+b.x+c.x)/3,(a.y+b.y+c.y)/3,(a.z+b.z+c.z)/3);
	m_vPos=m_vCentroid+offset;
	area.a-=m_vCentroid;
	area.b-=m_vCentroid;
	area.c-=m_vCentroid;
	area.a*=0.9;
	area.b*=0.9;
	area.c*=0.9;
	m_Type = MY_RAND(2);
	m_vTriArea=area;

	m_Height = (MY_RAND(MaxHeight/2)+1)+(MaxHeight/2);
	
	
	switch(m_Type)
	{
	case PYRAMID:
	GenPyramid();
	break;
	case CORNER:
	GenCorner();
	break;
	case TRIROUND:
	//GenRoundedTri();
	break;
	}
	

	//GenPyramid();
	//GenCorner();
	//GenRoundedTri();
	HRESULT hr;
	
	V(m_pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT ,0,0,0,0));
	V(D3DXComputeNormals(m_pMesh,0));
}
void Building::Generate(D3DXVECTOR3 centre, D3DXVECTOR3 area)
{
	HRESULT hr;
	const int height=32;
	const int width=32;
	Texture* t =new Texture;

	V( D3DXCreateTexture(TheD3DApp::Instance()->GetD3DDev(),width,height,D3DX_DEFAULT,D3DUSAGE_DYNAMIC,
		D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&t->m_pTex));

	D3DCOLORVALUE color[height*width];
	for (int i=0;i<width*height;++i)
	{
		int x=i%width;
		int y=(i-x)/width;
		color[i].r=MY_RAND(100)/100.0f;
		color[i].g=MY_RAND(100)/100.0f;
		color[i].b=MY_RAND(100)/100.0f;
		color[i].a=1;
		
	}
	D3DXFillTexture(t->m_pTex,CF,color);

	AddTexture(t);
	AddTexture(t);
	AddTexture(t);
	AddTexture(t);

	m_vPos = centre;
	m_vArea = area;
	m_Step=0;
	m_MaxStep=100;
	m_Stepped=false;
	m_Type = MY_RAND(4);
	int max_height = m_vArea.y;
	m_Height = (MY_RAND(max_height/2)+1)+(max_height/2);

	switch(m_Type)
	{
	case SIMPLE:
		GenSimple();
		break;
	case BLOCKY:
		GenBlocky();
		break;
	case MODERN:
		GenModern();
		break;
	case CLASSIC:
		//GenClassic();
		break;
	}

	
	//V(m_pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT ,0,0,0,0));
	//V(D3DXComputeNormals(m_pMesh,0));

}

void Building::GenSimple()
{	
	HRESULT hr;
	LPD3DXMESH mesh;
	D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),m_vArea.x/2,m_Height,m_vArea.z/2,&mesh,0);
	D3DXMATRIX T[1];
	LPD3DXMESH M[1];
	M[0]=mesh;
	D3DXMatrixTransformation(&T[0],0,0,0,0,0,&D3DXVECTOR3(0,m_Height/2,0));
	V(D3DXConcatenateMeshes(M,1,D3DXMESH_MANAGED,T,0,NULL,TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));
}

void Building::GenBlocky()
{
	int skipcount=0;
	float left,right,front,back,height;
	int half_widthHun = (m_vArea.x*100)/2;
	int half_depthHun = (m_vArea.z*100)/2;
	int max_height;
	bool skip=false;
	HRESULT hr;
	LPD3DXMESH mesh;
	D3DXMATRIX TransMatrix[2];
	LPD3DXMESH MeshBuffer[2];
	int Tiers = MY_RAND(5)+2;
	if(m_Step==0)
	{

		m_LastTierHeight=m_Height;

		D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),m_vArea.x,0.01,m_vArea.z,&m_pMesh,0);
		m_Step++;
	}
	for (unsigned int i=1;i<Tiers;++i)
	{

		left = (float)(MY_RAND(half_widthHun)+1)/100;
		right = (float)(MY_RAND(half_widthHun)+1)/100;
		front = (float)(MY_RAND(half_depthHun)+1)/100;
		back = (float)(MY_RAND(half_depthHun)+1)/100;
		max_height = m_LastTierHeight;
		height=(MY_RAND(max_height/2)+1)+(max_height/2);
		if (left <= m_maxLeft && right <= m_maxRight && front <= m_maxFront && back <= m_maxBack) 
		{skip = true;}


		if(height>2 && !skip)
		{
			m_maxLeft = max(left, m_maxLeft);
			m_maxRight = max(right, m_maxRight);
			m_maxFront = max(front, m_maxFront);
			m_maxBack = max(back, m_maxBack);


			m_LastTierHeight=height;
			D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),left+right,height,front+back,&mesh,0);

			float width = left+right;
			float hwidth =width/2;
			float tranx = hwidth-left;

			float depth = front+back;
			float hdepth = depth/2;
			float tranz = hdepth-front;

			MeshBuffer[0]=m_pMesh;
			MeshBuffer[1]=mesh;
			D3DXMatrixIdentity(&TransMatrix[0]);
			D3DXMatrixTransformation(&TransMatrix[1],0,0,0,0,0,&D3DXVECTOR3(tranx,height/2,tranz));

			V(D3DXConcatenateMeshes(MeshBuffer,2,D3DXMESH_MANAGED,TransMatrix,0,NULL,TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));

			m_Step++;
			m_NumSubsets++;
		}
		if(skip)
		{
			skipcount++;

			if(skipcount>5)
			{
				m_Step++;
				skipcount=0;
			}
		}
	}


}
enum ModernType
{
	MOD_CYLINDER,
	MOD_HELIX,
	MOD_NARROW,
	MOD_CONED
};
void Building::GenModern()
{
	int ModType=MY_RAND(3);

	HRESULT hr;
	int NumTris=36;
	int NumVerts=38;
	int ConeTiers;
	int ConeVerts;
	int ConeTris;
	LPD3DXMESH base;
	LPD3DXMESH cap;
	LPD3DXMESH sides;

	D3DXCreateMesh(NumTris,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&base);
	D3DXCreateMesh(NumTris,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&cap);
	D3DXCreateMesh(NumTris*2,(NumVerts*2)-2,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&sides);

	POSNORMUVVERTEX* pBaseVertices;
	POSNORMUVVERTEX* pSidesVertices;
	POSNORMUVVERTEX* pCapVertices;
	base->LockVertexBuffer(0, (void**)&pBaseVertices);
	sides->LockVertexBuffer(0,(void**)&pSidesVertices);
	cap->LockVertexBuffer(0,(void**)&pCapVertices);
	int scount=0;

	switch(ModType)
	{
	case MOD_CYLINDER:

		//centre of circle
		pBaseVertices[0].Pos=D3DXVECTOR3(0,0,0);
		pBaseVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pBaseVertices[0].UV=D3DXVECTOR2(0,0);

		pCapVertices[0].Pos=D3DXVECTOR3(0,m_Height,0);
		pCapVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pCapVertices[0].UV=D3DXVECTOR2(0,1);

		//points around circle
		for (unsigned int i=0;i<NumVerts-1;++i)
		{
			float x = -sin((i*10)*(M_PI/180))*(m_vArea.x/2);
			float z = cos((i*10)*(M_PI/180))*(m_vArea.z/2);
			pBaseVertices[i+1].Pos=D3DXVECTOR3(x,0,z);
			pBaseVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pBaseVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),0);

			pCapVertices[i+1].Pos=D3DXVECTOR3(x,m_Height,z);
			pCapVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pCapVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),1);
		}

		break;


	case MOD_CONED:
		ConeTiers=9;
		ConeVerts=NumVerts+(ConeTiers*(NumVerts-1))-10;
		ConeTris=NumTris+(ConeTiers*(NumTris*2));
		V(D3DXCreateMesh(ConeTris*2,ConeVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&cap));
		V(cap->LockVertexBuffer(0,(void**)&pCapVertices));
		//centre of circle
		pBaseVertices[0].Pos=D3DXVECTOR3(0,0,0);
		pBaseVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pBaseVertices[0].UV=D3DXVECTOR2(0,0);

		pCapVertices[0].Pos=D3DXVECTOR3(0,m_Height,0);
		pCapVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pCapVertices[0].UV=D3DXVECTOR2(0,1);

		//points around circle
		for (unsigned int i=0;i<NumVerts-1;++i)
		{
			float x = -sin((i*10)*(M_PI/180))*(m_vArea.x/2);
			float z = cos((i*10)*(M_PI/180))*(m_vArea.z/2);
			pBaseVertices[i+1].Pos=D3DXVECTOR3(x,0,z);
			pBaseVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pBaseVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),0);

			pCapVertices[i+1].Pos=D3DXVECTOR3(x,m_Height,z);
			pCapVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pCapVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),1);
		}

		for(unsigned int i=1;i<ConeTiers+1;++i)
		{
			float additionalHeight = (i*(m_Height/(ConeTiers*5)));
			for(unsigned int j=0;j<NumVerts-1;++j)
			{
				float x;
				float z;
				if(i<ConeTiers)
				{
					float r = ((float)i*((float)90/ConeTiers))*(M_PI/180);
					x = -sin((j*10)*(M_PI/180))*((m_vArea.x/2)*cos(r));
					z = cos((j*10)*(M_PI/180))*((m_vArea.x/2)*cos(r));
				}
				else
				{
					x=0;
					z=0;
				}
				pCapVertices[j+(i*NumTris)+1].Pos=D3DXVECTOR3(x,m_Height+additionalHeight,z);
				pCapVertices[j+(i*NumTris)+1].Norm=D3DXVECTOR3(0,1,0);
				pCapVertices[j+(i*NumTris)+1].UV=D3DXVECTOR2(0,0);
			}

		}

		break;


		float helixStart;
		float helixStep;
	case MOD_HELIX:

		helixStart=(MY_RAND(m_Height));
		helixStep=(m_Height-helixStart)/NumTris;
		//centre of circle
		pBaseVertices[0].Pos=D3DXVECTOR3(0,0,0);
		pBaseVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pBaseVertices[0].UV=D3DXVECTOR2(0,0);

		pCapVertices[0].Pos=D3DXVECTOR3(0,m_Height,0);
		pCapVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pCapVertices[0].UV=D3DXVECTOR2(0,1);

		//points around circle
		for (unsigned int i=0;i<NumVerts-1;++i)
		{
			float x = -sin((i*10)*(M_PI/180))*(m_vArea.x/2);
			float z = cos((i*10)*(M_PI/180))*(m_vArea.z/2);
			pBaseVertices[i+1].Pos=D3DXVECTOR3(x,0,z);
			pBaseVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pBaseVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),0);

			pCapVertices[i+1].Pos=D3DXVECTOR3(x,helixStart+(helixStep*i),z);
			pCapVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pCapVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),1);
		}
		break;

		int halfWidthHun;
		float topDecreaseX, topDecreaseZ;
	case MOD_NARROW:

		halfWidthHun=(m_vArea.x/2)*100;
		topDecreaseX= (float)(MY_RAND(halfWidthHun)/100);

		//make sure the top is big enough for both directions
		if(topDecreaseX>(m_vArea.z/2))
		{
			halfWidthHun=(m_vArea.z/2)*100;
			topDecreaseZ= (float)(MY_RAND(halfWidthHun)/100);
		}
		else
		{
			topDecreaseZ=topDecreaseX;
		}
		//centre of circle
		pBaseVertices[0].Pos=D3DXVECTOR3(0,0,0);
		pBaseVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pBaseVertices[0].UV=D3DXVECTOR2(0,0);

		pCapVertices[0].Pos=D3DXVECTOR3(0,m_Height,0);
		pCapVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pCapVertices[0].UV=D3DXVECTOR2(0,1);

		//points around circle
		for (unsigned int i=0;i<NumVerts-1;++i)
		{
			float x = -sin((i*10)*(M_PI/180))*(m_vArea.x/2);
			float z = cos((i*10)*(M_PI/180))*(m_vArea.z/2);
			float x2 = -sin((i*10)*(M_PI/180))*((m_vArea.x/2)-topDecreaseX);
			float z2 = cos((i*10)*(M_PI/180))*((m_vArea.z/2)-topDecreaseZ);
			pBaseVertices[i+1].Pos=D3DXVECTOR3(x,0,z);
			pBaseVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pBaseVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),0);

			pCapVertices[i+1].Pos=D3DXVECTOR3(x2,m_Height,z2);
			pCapVertices[i+1].Norm=D3DXVECTOR3(0,1,0);
			pCapVertices[i+1].UV=D3DXVECTOR2((float)(i+1)/(NumVerts-1),1);
		}
		break;
	}

	//make 2 verts for each vert on the circle
	for (unsigned int i=1;i<NumVerts;++i)
	{
		pSidesVertices[scount]=pBaseVertices[i];
		scount++;
		pSidesVertices[scount]=pCapVertices[i];
		scount++;

	}
	V(base->UnlockVertexBuffer());
	V(sides->UnlockVertexBuffer());
	V(cap->UnlockVertexBuffer());

	WORD *BaseIndexData=NULL;
	V(base->LockIndexBuffer( 0, (void**)&BaseIndexData ));
	WORD *CapIndexData=NULL;
	V(cap->LockIndexBuffer( 0, (void**)&CapIndexData ));
	int indCount=0;
	for(unsigned int i=0; i<NumTris;++i)
	{
		BaseIndexData[indCount]=0;
		CapIndexData[indCount]=0;
		indCount++;
		BaseIndexData[indCount]=i+1;
		CapIndexData[indCount]=i+1;
		indCount++;
		if(i!=NumTris-1)
		{
			BaseIndexData[indCount]=i+2;
			CapIndexData[indCount]=i+2;
			indCount++;
		}
		else
		{
			BaseIndexData[indCount]=1;
			CapIndexData[indCount]=1;
			indCount++;
		}

	}
	V(base->UnlockIndexBuffer());

	if(ModType==MOD_CONED)
	{
		for(unsigned int i=NumTris;i<ConeTris;i++)
		{
			CapIndexData[indCount++]=i+1;
			CapIndexData[indCount++]=i+1+NumTris;
			CapIndexData[indCount++]=i+2;

			CapIndexData[indCount++]=i+2;
			CapIndexData[indCount++]=i+1+NumTris;
			CapIndexData[indCount++]=i+2+NumTris;

			/*
			CapIndexData[indCount++]=i+2;
			CapIndexData[indCount++]=i+2+NumTris;
			CapIndexData[indCount++]=i+3;

			CapIndexData[indCount++]=i+3;
			CapIndexData[indCount++]=i+2+NumTris;
			CapIndexData[indCount++]=i+3+NumTris;
			*/
		}
	}
	V(cap->UnlockIndexBuffer());


	WORD *SidesIndexData=NULL;
	V(sides->LockIndexBuffer( 0, (void**)&SidesIndexData ));
	indCount=0;
	for(unsigned int i=0; i<NumTris*2;i+=2)
	{
		if(i<(NumTris*2)-1)
		{
			SidesIndexData[indCount++]=i;
			SidesIndexData[indCount++]=i+1;
			SidesIndexData[indCount++]=i+2;

			SidesIndexData[indCount++]=i+2;
			SidesIndexData[indCount++]=i+1;
			SidesIndexData[indCount++]=i+3;
		}
		else
		{
			SidesIndexData[indCount++]=i;
			SidesIndexData[indCount++]=i+1;
			SidesIndexData[indCount++]=0;

			SidesIndexData[indCount++]=0;
			SidesIndexData[indCount++]=i+1;
			SidesIndexData[indCount++]=1;
		}
	}
	V(sides->UnlockIndexBuffer());

	LPD3DXMESH pMeshes[3];
	pMeshes[0]=base;
	pMeshes[1]=sides;
	pMeshes[2]=cap;
	D3DXMATRIX TransMatrix[3];
	D3DXMatrixIdentity(&TransMatrix[0]);
	D3DXMatrixIdentity(&TransMatrix[1]);
	D3DXMatrixIdentity(&TransMatrix[2]);

	m_NumSubsets+=2;
	V(D3DXConcatenateMeshes(pMeshes,3,D3DXMESH_MANAGED,TransMatrix,0,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));

	//m_pMesh=cap;
}

void Building::GenClassic()
{  
	HRESULT hr;
	bool narrow = MY_RAND(2);
	int narAmount=MY_RAND(5)+4;
	int narStepX=m_vArea.x/narAmount;
	int narStepZ=m_vArea.z/narAmount;
	int maxheight=m_vArea.y;
	m_Height = (MY_RAND(maxheight/2))+(maxheight/2);
	float maxTierSize=m_Height/10;
	float tierSize=(MY_RAND(maxTierSize))+0.1;
	float lip = (m_vArea.x/100)*MY_RAND(4);
	LPD3DXMESH mesh1;
	LPD3DXMESH mesh2;
	D3DXMATRIX TransMatrix[3];
	V(D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),m_vArea.x,tierSize,m_vArea.z,&m_pMesh,0));
	D3DXMatrixTransformation(&TransMatrix[0],0,0,0,0,0,&D3DXVECTOR3(0,(tierSize/2),0));
	int top=tierSize;
	int tierNum=0;
	while(top<m_Height-(tierSize*2))
	{
		int x =m_vArea.x;
		int z =m_vArea.z;
		if(narrow)
		{
			tierSize=tierSize/(narAmount-3);
			if(tierSize<1)
			{
				tierSize=1;
			}
			int newx=narStepX*tierNum;
			if(newx<(m_vArea.x/2))
			{
				x-=newx;
			}
			else
			{
				x=1;
			}
			int newz=narStepZ*tierNum;
			if(newz<(m_vArea.z/2))
			{
				z-=newz;
			}
			else
			{
				z=1;
			}
		}
		int rel = (MY_RAND(4)+1);
		int maxSecSize = (m_Height-(top+tierSize));
		int secSize = maxSecSize/rel;
		if(secSize==0)
		{
			secSize=tierSize;
		}

		V(D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),x,secSize,z,&mesh1,0));
		V(D3DXCreateBox(TheD3DApp::Instance()->GetD3DDev(),x+lip,tierSize,z+lip,&mesh2,0));

		LPD3DXMESH pMeshes[3];
		pMeshes[0]=m_pMesh;
		pMeshes[1]=mesh1;
		pMeshes[2]=mesh2;
		float y1=(float)top+((float)secSize/2);
		float y2=(float)top+secSize+((float)tierSize/2);
		D3DXMatrixTransformation(&TransMatrix[1],0,0,0,0,0,&D3DXVECTOR3(0,y1,0));
		D3DXMatrixTransformation(&TransMatrix[2],0,0,0,0,0,&D3DXVECTOR3(0,y2,0));

		V(D3DXConcatenateMeshes(pMeshes,3,D3DXMESH_MANAGED,TransMatrix,0,NULL,TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));

		D3DXMatrixIdentity(&TransMatrix[0]);

		top+=(secSize+tierSize);
		m_NumSubsets+=2;
		tierNum++;
		if(x==1 || z==1)
		{
			top=m_Height;
		}
	}
	//consider spike
	bool spike = COIN_FLIP;
	if (!narrow && spike)
	{
		V(D3DXCreateMesh(4,5,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&mesh1));
		POSNORMUVVERTEX* pVertices;
		V(mesh1->LockVertexBuffer(0,(void**)&pVertices));
		pVertices[0].Pos=D3DXVECTOR3(0,tierSize,0);
		pVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pVertices[0].UV=D3DXVECTOR2(0,0);

		pVertices[1].Pos=D3DXVECTOR3((m_vArea.x/2),0,(m_vArea.z/2));
		pVertices[1].Norm=D3DXVECTOR3(0,1,0);
		pVertices[1].UV=D3DXVECTOR2(0,0);
		pVertices[2].Pos=D3DXVECTOR3(-(m_vArea.x/2),0,(m_vArea.z/2));
		pVertices[2].Norm=D3DXVECTOR3(0,1,0);
		pVertices[2].UV=D3DXVECTOR2(0,0);
		pVertices[3].Pos=D3DXVECTOR3(-(m_vArea.x/2),0,-(m_vArea.z/2));
		pVertices[3].Norm=D3DXVECTOR3(0,1,0);
		pVertices[3].UV=D3DXVECTOR2(0,0);
		pVertices[4].Pos=D3DXVECTOR3((m_vArea.x/2),0,-(m_vArea.z/2));
		pVertices[4].Norm=D3DXVECTOR3(0,1,0);
		pVertices[5].UV=D3DXVECTOR2(0,0);
		V(mesh1->UnlockVertexBuffer());

		WORD *IndexData=NULL;
		int indcount=0;
		V(mesh1->LockIndexBuffer( 0, (void**)&IndexData ));
		IndexData[indcount++]=0;
		IndexData[indcount++]=1;
		IndexData[indcount++]=2;

		IndexData[indcount++]=0;
		IndexData[indcount++]=2;
		IndexData[indcount++]=3;

		IndexData[indcount++]=0;
		IndexData[indcount++]=3;
		IndexData[indcount++]=4;

		IndexData[indcount++]=0;
		IndexData[indcount++]=4;
		IndexData[indcount++]=1;
		V(mesh1->UnlockIndexBuffer());


		D3DXMATRIX TransM[2];
		D3DXMatrixIdentity(&TransM[0]);
		D3DXMatrixTransformation(&TransM[1],0,0,0,0,0,&D3DXVECTOR3(0,top,0));
		LPD3DXMESH pMeshes[2];
		pMeshes[0]=m_pMesh;
		pMeshes[1]=mesh1;
		V(D3DXConcatenateMeshes(pMeshes,2,D3DXMESH_MANAGED,TransM,0,NULL,TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));
		m_NumSubsets++;
	}

}
void Building::NextStep()
{
	m_MaxStep++;
	//GenBlocky();
}

void Building::GenPyramid()
{
	HRESULT hr;
	const int height=32;
	const int width=32;
	Texture* t =new Texture;

	V( D3DXCreateTexture(TheD3DApp::Instance()->GetD3DDev(),width,height,D3DX_DEFAULT,D3DUSAGE_DYNAMIC,
		D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&t->m_pTex));

	D3DCOLORVALUE color[height*width];
	for (int i=0;i<width*height;++i)
	{
		int x=i%width;
		int y=(i-x)/width;
		color[i].r=MY_RAND(100)/100.0f;
		color[i].g=MY_RAND(100)/100.0f;
		color[i].b=MY_RAND(100)/100.0f;
		color[i].a=1;

	}
	D3DXFillTexture(t->m_pTex,CF,color);
	V(D3DXCreateMesh(4,4,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));
	POSNORMUVVERTEX* pVertices;
	V(m_pMesh->LockVertexBuffer(0, (void**)&pVertices));
	pVertices[0].Pos=m_vTriArea.a;
	pVertices[0].Norm=D3DXVECTOR3(0,1,0);
	pVertices[0].UV=D3DXVECTOR2(0,0);

	pVertices[1].Pos=m_vTriArea.b;
	pVertices[1].Norm=D3DXVECTOR3(0,1,0);
	pVertices[1].UV=D3DXVECTOR2((float)1/3,0);

	pVertices[2].Pos=m_vTriArea.c;
	pVertices[2].Norm=D3DXVECTOR3(0,1,0);
	pVertices[2].UV=D3DXVECTOR2((float)2/3,0);

	pVertices[3].Pos=D3DXVECTOR3(0,m_Height,0);
	pVertices[3].Norm=D3DXVECTOR3(0,1,0);
	pVertices[3].UV=D3DXVECTOR2(0,1);
	V(m_pMesh->UnlockVertexBuffer());

	WORD *IndexData=NULL;
	V(m_pMesh->LockIndexBuffer( 0, (void**)&IndexData ));
	int indcount=0;
	IndexData[indcount++]=0;
	IndexData[indcount++]=1;
	IndexData[indcount++]=2;

	IndexData[indcount++]=2;
	IndexData[indcount++]=0;
	IndexData[indcount++]=3;

	IndexData[indcount++]=0;
	IndexData[indcount++]=1;
	IndexData[indcount++]=3;

	IndexData[indcount++]=1;
	IndexData[indcount++]=2;
	IndexData[indcount++]=3;
	V(m_pMesh->UnlockIndexBuffer());
	AddTexture(t);
}

void Building::GenCorner()
{
	HRESULT hr;
	const int height=32;
	const int width=32;
	Texture* t =new Texture;

	V( D3DXCreateTexture(TheD3DApp::Instance()->GetD3DDev(),width,height,D3DX_DEFAULT,D3DUSAGE_DYNAMIC,
		D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&t->m_pTex));

	D3DCOLORVALUE color[height*width];
	for (int i=0;i<width*height;++i)
	{
		int x=i%width;
		int y=(i-x)/width;
		color[i].r=MY_RAND(100)/100.0f;
		color[i].g=MY_RAND(100)/100.0f;
		color[i].b=MY_RAND(100)/100.0f;
		color[i].a=1;

	}
	D3DXFillTexture(t->m_pTex,CF,color);


	bool narrow = COIN_FLIP;
	bool tiered = COIN_FLIP;
	bool cutCorners = COIN_FLIP;
	float cornerCutOff=(MY_RAND(4)+1)*0.1;
	int rel = MY_RAND(10)+1;
	int tierSize = m_Height/rel;
	if(tierSize<1)
	{tierSize=1;}
	int lidSize = MY_RAND(m_Height/10)+1;
	float lip = 0;
	if(tiered)
	{lip= (MY_RAND(4)+1)/50;}
	float curHeight=0;
	int NumFaces=12;
	int NumVerts=8;
	int indcount=0;
	int vertCount=0;
	int tierNum=0;
	float tierStep=0;
	if(narrow)
	{
		tierStep=0.1;
	}
	if(cutCorners)
	{
		NumFaces*=2;
		NumVerts*=2;
	}

	D3DXCreateMesh(NumFaces,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&m_pMesh);
	POSNORMUVVERTEX* pVertices;
	V(m_pMesh->LockVertexBuffer(0,(void**)&pVertices));
	WORD *IndexData=NULL;
	V(m_pMesh->LockIndexBuffer( 0, (void**)&IndexData ));
	if(cutCorners)
	{
		pVertices[vertCount].Pos=D3DXVECTOR3(0,0,0);
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)0/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,0);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,0);
		vertCount++;

		int height=m_Height;

		if(narrow)
		{
			height = tierSize;
		}
		if(tiered)
		{
			height = lidSize;
		}
		
		pVertices[vertCount].Pos=D3DXVECTOR3(0,height,0);
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2(0,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,1);
		vertCount++;
		pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
		pVertices[vertCount].Pos*=1+lip;
		pVertices[vertCount].Pos.y=height;
		pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
		pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,1);
		vertCount++;

		curHeight=height;

		for(unsigned int i=1;i<7;++i)
		{
			if(i<6)
			{
				IndexData[indcount++]=0;
				IndexData[indcount++]=i;
				IndexData[indcount++]=i+1;

				IndexData[indcount++]=i;
				IndexData[indcount++]=i+1;
				IndexData[indcount++]=i+7;

				IndexData[indcount++]=i+1;
				IndexData[indcount++]=i+7;
				IndexData[indcount++]=i+8;

				IndexData[indcount++]=7;
				IndexData[indcount++]=i+7;
				IndexData[indcount++]=i+8;
			}
			else
			{
				IndexData[indcount++]=0;
				IndexData[indcount++]=6;
				IndexData[indcount++]=1;

				IndexData[indcount++]=6;
				IndexData[indcount++]=1;
				IndexData[indcount++]=13;

				IndexData[indcount++]=1;
				IndexData[indcount++]=13;
				IndexData[indcount++]=8;

				IndexData[indcount++]=7;
				IndexData[indcount++]=13;
				IndexData[indcount++]=8;
			}
		}
	}


	else
	{
		pVertices[0].Pos=D3DXVECTOR3(0,0,0);
		pVertices[0].Norm=D3DXVECTOR3(0,1,0);
		pVertices[0].UV=D3DXVECTOR2(0,0);


		pVertices[1].Pos=m_vTriArea.a;
		pVertices[1].Pos*=1+lip;
		pVertices[1].Norm=D3DXVECTOR3(0,1,0);
		pVertices[1].UV=D3DXVECTOR2((float)1/3,0);

		pVertices[2].Pos=m_vTriArea.b;
		pVertices[2].Pos*=1+lip;
		pVertices[2].Norm=D3DXVECTOR3(0,1,0);
		pVertices[2].UV=D3DXVECTOR2((float)2/3,0);

		pVertices[3].Pos=m_vTriArea.c;
		pVertices[3].Pos*=1+lip;
		pVertices[3].Norm=D3DXVECTOR3(0,1,0);
		pVertices[3].UV=D3DXVECTOR2((float)3/3,0);

		int height=m_Height;
		if(tiered)
		{
			height = lidSize;
		}
		if(narrow)
		{
			height = tierSize;
		}

		pVertices[4].Pos=D3DXVECTOR3(0,height,0);
		pVertices[4].Norm=D3DXVECTOR3(0,1,0);
		pVertices[4].UV=D3DXVECTOR2(0,1);

		pVertices[5].Pos=m_vTriArea.a;
		pVertices[5].Pos*=1+lip;
		pVertices[5].Pos.y=height;
		pVertices[5].Norm=D3DXVECTOR3(0,1,0);
		pVertices[5].UV=D3DXVECTOR2((float)1/3,1);

		pVertices[6].Pos=m_vTriArea.b;
		pVertices[6].Pos*=1+lip;
		pVertices[6].Pos.y=height;
		pVertices[6].Norm=D3DXVECTOR3(0,1,0);
		pVertices[6].UV=D3DXVECTOR2((float)2/3,1);

		pVertices[7].Pos=m_vTriArea.c;
		pVertices[7].Pos*=1+lip;
		pVertices[7].Pos.y=height;
		pVertices[7].Norm=D3DXVECTOR3(0,1,0);
		pVertices[7].UV=D3DXVECTOR2((float)3/3,1);

		curHeight=height;

		for(unsigned int i=1;i<4;++i)
		{
			if(i<3)
			{
				IndexData[indcount++]=0;
				IndexData[indcount++]=i;
				IndexData[indcount++]=i+1;

				IndexData[indcount++]=i;
				IndexData[indcount++]=i+1;
				IndexData[indcount++]=i+4;

				IndexData[indcount++]=i+1;
				IndexData[indcount++]=i+4;
				IndexData[indcount++]=i+5;

				IndexData[indcount++]=4;
				IndexData[indcount++]=i+4;
				IndexData[indcount++]=i+5;
			}
			else
			{
				IndexData[indcount++]=0;
				IndexData[indcount++]=3;
				IndexData[indcount++]=1;

				IndexData[indcount++]=3;
				IndexData[indcount++]=1;
				IndexData[indcount++]=7;

				IndexData[indcount++]=1;
				IndexData[indcount++]=7;
				IndexData[indcount++]=5;

				IndexData[indcount++]=4;
				IndexData[indcount++]=7;
				IndexData[indcount++]=5;
			}
		}

	}

	V(m_pMesh->UnlockVertexBuffer());
	V(m_pMesh->UnlockIndexBuffer());

	if(!narrow && !tiered)
	{
		AddTexture(t);
	}
	else
	{
		AddTexture(t);
	}

	while (curHeight<m_Height)
	{
		LPD3DXMESH tier;
		tierNum++;
		D3DXCreateMesh(NumFaces,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&tier);
		pVertices=NULL;
		V(tier->LockVertexBuffer(0,(void**)&pVertices));
		IndexData=NULL;
		V(tier->LockIndexBuffer( 0, (void**)&IndexData ));
		indcount=0;
		vertCount=0;
		int height = tierSize;
		if((tierStep*tierNum)>1)
		{
			break;
		}
		if(cutCorners)
		{
			pVertices[vertCount].Pos=D3DXVECTOR3(0,0,0);
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2(0,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,0);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,0);
			vertCount++;


			

			pVertices[vertCount].Pos=D3DXVECTOR3(0,height,0);
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2(0,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,1);
			vertCount++;
			pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
			pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
			pVertices[vertCount].Pos.y=height;
			pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
			pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,1);
			vertCount++;

			curHeight+=height;

			for(unsigned int i=1;i<7;++i)
			{
				if(i<6)
				{
					IndexData[indcount++]=0;
					IndexData[indcount++]=i;
					IndexData[indcount++]=i+1;

					IndexData[indcount++]=i;
					IndexData[indcount++]=i+1;
					IndexData[indcount++]=i+7;

					IndexData[indcount++]=i+1;
					IndexData[indcount++]=i+7;
					IndexData[indcount++]=i+8;

					IndexData[indcount++]=7;
					IndexData[indcount++]=i+7;
					IndexData[indcount++]=i+8;
				}
				else
				{
					IndexData[indcount++]=0;
					IndexData[indcount++]=6;
					IndexData[indcount++]=1;

					IndexData[indcount++]=6;
					IndexData[indcount++]=1;
					IndexData[indcount++]=13;

					IndexData[indcount++]=1;
					IndexData[indcount++]=13;
					IndexData[indcount++]=8;

					IndexData[indcount++]=7;
					IndexData[indcount++]=13;
					IndexData[indcount++]=8;
				}
			}
		}


		else 
		{
			pVertices[0].Pos=D3DXVECTOR3(0,0,0);
			pVertices[0].Norm=D3DXVECTOR3(0,1,0);
			pVertices[0].UV=D3DXVECTOR2(0,0);

			pVertices[1].Pos=m_vTriArea.a;
			pVertices[1].Pos*=(1-(tierStep*tierNum));
			pVertices[1].Norm=D3DXVECTOR3(0,1,0);
			pVertices[1].UV=D3DXVECTOR2((float)1/3,0);

			pVertices[2].Pos=m_vTriArea.b;
			pVertices[2].Pos*=(1-(tierStep*tierNum));
			pVertices[2].Norm=D3DXVECTOR3(0,1,0);
			pVertices[2].UV=D3DXVECTOR2((float)2/3,0);

			pVertices[3].Pos=m_vTriArea.c;
			pVertices[3].Pos*=(1-(tierStep*tierNum));
			pVertices[3].Norm=D3DXVECTOR3(0,1,0);
			pVertices[3].UV=D3DXVECTOR2((float)3/3,0);




			pVertices[4].Pos=D3DXVECTOR3(0,height,0);
			pVertices[4].Norm=D3DXVECTOR3(0,1,0);
			pVertices[4].UV=D3DXVECTOR2(0,1);

			pVertices[5].Pos=m_vTriArea.a+D3DXVECTOR3(0,height,0);
			pVertices[5].Pos*=(1-(tierStep*tierNum));
			pVertices[5].Pos.y=height;
			pVertices[5].Norm=D3DXVECTOR3(0,1,0);
			pVertices[5].UV=D3DXVECTOR2((float)1/3,1);

			pVertices[6].Pos=m_vTriArea.b+D3DXVECTOR3(0,height,0);
			pVertices[6].Pos*=(1-(tierStep*tierNum));
			pVertices[6].Pos.y=height;
			pVertices[6].Norm=D3DXVECTOR3(0,1,0);
			pVertices[6].UV=D3DXVECTOR2((float)2/3,1);

			pVertices[7].Pos=m_vTriArea.c+D3DXVECTOR3(0,height,0);
			pVertices[7].Pos*=(1-(tierStep*tierNum));
			pVertices[7].Pos.y=height;
			pVertices[7].Norm=D3DXVECTOR3(0,1,0);
			pVertices[7].UV=D3DXVECTOR2((float)3/3,1);

			curHeight+=height;

			for(unsigned int i=1;i<4;++i)
			{
				if(i<3)
				{
					IndexData[indcount++]=0;
					IndexData[indcount++]=i;
					IndexData[indcount++]=i+1;

					IndexData[indcount++]=i;
					IndexData[indcount++]=i+1;
					IndexData[indcount++]=i+4;

					IndexData[indcount++]=i+1;
					IndexData[indcount++]=i+4;
					IndexData[indcount++]=i+5;

					IndexData[indcount++]=4;
					IndexData[indcount++]=i+4;
					IndexData[indcount++]=i+5;
				}
				else
				{
					IndexData[indcount++]=0;
					IndexData[indcount++]=3;
					IndexData[indcount++]=1;

					IndexData[indcount++]=3;
					IndexData[indcount++]=1;
					IndexData[indcount++]=7;

					IndexData[indcount++]=1;
					IndexData[indcount++]=7;
					IndexData[indcount++]=5;

					IndexData[indcount++]=4;
					IndexData[indcount++]=7;
					IndexData[indcount++]=5;
				}
			}

		}

		V(tier->UnlockVertexBuffer());
		V(tier->UnlockIndexBuffer());


		LPD3DXMESH lid;
		if(tiered)
		{
			int height = lidSize;
			
			D3DXCreateMesh(NumFaces,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&lid);
			pVertices=NULL;
			V(lid->LockVertexBuffer(0,(void**)&pVertices));
			IndexData=NULL;
			V(lid->LockIndexBuffer( 0, (void**)&IndexData ));
			indcount=0;
			vertCount=0;
			if(cutCorners)
			{
				pVertices[vertCount].Pos=D3DXVECTOR3(0,0,0);
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2(0,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,0);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,0);
				vertCount++;


				pVertices[vertCount].Pos=D3DXVECTOR3(0,height,0);
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2(0,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ca*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)1/6,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.a-(m_vTriArea.ba*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)2/6,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.ab*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)3/6,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.b-(m_vTriArea.cb*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)4/6,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.bc*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)5/6,1);
				vertCount++;
				pVertices[vertCount].Pos=m_vTriArea.c-(m_vTriArea.ac*cornerCutOff);
				pVertices[vertCount].Pos*=1+lip;
				pVertices[vertCount].Pos*=(1-(tierStep*tierNum));
				pVertices[vertCount].Pos.y=height;
				pVertices[vertCount].Norm=D3DXVECTOR3(0,1,0);
				pVertices[vertCount].UV=D3DXVECTOR2((float)6/6,1);
				vertCount++;

				curHeight+=height;

				for(unsigned int i=1;i<7;++i)
				{
					if(i<6)
					{
						IndexData[indcount++]=0;
						IndexData[indcount++]=i;
						IndexData[indcount++]=i+1;

						IndexData[indcount++]=i;
						IndexData[indcount++]=i+1;
						IndexData[indcount++]=i+7;

						IndexData[indcount++]=i+1;
						IndexData[indcount++]=i+7;
						IndexData[indcount++]=i+8;

						IndexData[indcount++]=7;
						IndexData[indcount++]=i+7;
						IndexData[indcount++]=i+8;
					}
					else
					{
						IndexData[indcount++]=0;
						IndexData[indcount++]=6;
						IndexData[indcount++]=1;

						IndexData[indcount++]=6;
						IndexData[indcount++]=1;
						IndexData[indcount++]=13;

						IndexData[indcount++]=1;
						IndexData[indcount++]=13;
						IndexData[indcount++]=8;

						IndexData[indcount++]=7;
						IndexData[indcount++]=13;
						IndexData[indcount++]=8;
					}
				}
			}


			else
			{
				pVertices[0].Pos=D3DXVECTOR3(0,0,0);
				pVertices[0].Norm=D3DXVECTOR3(0,1,0);
				pVertices[0].UV=D3DXVECTOR2(0,0);

				pVertices[1].Pos=m_vTriArea.a;
				pVertices[1].Pos*=1+lip;
				pVertices[1].Pos*=(1-(tierStep*tierNum));
				pVertices[1].Norm=D3DXVECTOR3(0,1,0);
				pVertices[1].UV=D3DXVECTOR2((float)1/3,0);

				pVertices[2].Pos=m_vTriArea.b;
				pVertices[2].Pos*=1+lip;
				pVertices[2].Pos*=(1-(tierStep*tierNum));
				pVertices[2].Norm=D3DXVECTOR3(0,1,0);
				pVertices[2].UV=D3DXVECTOR2((float)2/3,0);

				pVertices[3].Pos=m_vTriArea.c;
				pVertices[3].Pos*=1+lip;
				pVertices[3].Pos*=(1-(tierStep*tierNum));
				pVertices[3].Norm=D3DXVECTOR3(0,1,0);
				pVertices[3].UV=D3DXVECTOR2((float)3/3,0);


				pVertices[4].Pos=D3DXVECTOR3(0,height,0);
				pVertices[4].Norm=D3DXVECTOR3(0,1,0);
				pVertices[4].UV=D3DXVECTOR2(0,1);

				pVertices[5].Pos=m_vTriArea.a+D3DXVECTOR3(0,height,0);
				pVertices[5].Pos*=1+lip;
				pVertices[5].Pos*=(1-(tierStep*tierNum));
				pVertices[5].Pos.y=height;
				pVertices[5].Norm=D3DXVECTOR3(0,1,0);
				pVertices[5].UV=D3DXVECTOR2((float)1/3,1);

				pVertices[6].Pos=m_vTriArea.b+D3DXVECTOR3(0,height,0);
				pVertices[6].Pos*=1+lip;
				pVertices[6].Pos*=(1-(tierStep*tierNum));
				pVertices[5].Pos.y=height;
				pVertices[6].Norm=D3DXVECTOR3(0,1,0);
				pVertices[6].UV=D3DXVECTOR2((float)2/3,1);

				pVertices[7].Pos=m_vTriArea.c+D3DXVECTOR3(0,height,0);
				pVertices[7].Pos*=1+lip;
				pVertices[7].Pos*=(1-(tierStep*tierNum));
				pVertices[5].Pos.y=height;
				pVertices[7].Norm=D3DXVECTOR3(0,1,0);
				pVertices[7].UV=D3DXVECTOR2((float)3/3,1);

				curHeight+=height;

				for(unsigned int i=1;i<4;++i)
				{
					if(i<3)
					{
						IndexData[indcount++]=0;
						IndexData[indcount++]=i;
						IndexData[indcount++]=i+1;

						IndexData[indcount++]=i;
						IndexData[indcount++]=i+1;
						IndexData[indcount++]=i+4;

						IndexData[indcount++]=i+1;
						IndexData[indcount++]=i+4;
						IndexData[indcount++]=i+5;

						IndexData[indcount++]=4;
						IndexData[indcount++]=i+4;
						IndexData[indcount++]=i+5;
					}
					else
					{
						IndexData[indcount++]=0;
						IndexData[indcount++]=3;
						IndexData[indcount++]=1;

						IndexData[indcount++]=3;
						IndexData[indcount++]=1;
						IndexData[indcount++]=7;

						IndexData[indcount++]=1;
						IndexData[indcount++]=7;
						IndexData[indcount++]=5;

						IndexData[indcount++]=4;
						IndexData[indcount++]=7;
						IndexData[indcount++]=5;
					}
				}

			}
			
			V(lid->UnlockVertexBuffer());
			V(lid->UnlockIndexBuffer());
		}

		
		
		if(tiered)
		{
			LPD3DXMESH meshs[3];
			meshs[0]=m_pMesh;
			meshs[1]=tier;
			meshs[2]=lid;
			D3DXMATRIX TransM[3];
			D3DXMatrixIdentity(&TransM[0]);
			D3DXMatrixTransformation(&TransM[1],0,0,0,0,0,&D3DXVECTOR3(0,curHeight-lidSize-tierSize,0));
			D3DXMatrixTransformation(&TransM[2],0,0,0,0,0,&D3DXVECTOR3(0,curHeight-lidSize,0));
			V(D3DXConcatenateMeshes(meshs,3,D3DXMESH_MANAGED,TransM,0,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));
			AddTexture(t);
			AddTexture(t);
		}
		else // narrow only
		{
			LPD3DXMESH meshs[2];
			meshs[0]=m_pMesh;
			meshs[1]=tier;

			D3DXMATRIX TransM[2];
			D3DXMatrixIdentity(&TransM[0]);
			D3DXMatrixTransformation(&TransM[1],0,0,0,0,0,&D3DXVECTOR3(0,curHeight-tierSize,0));

			V(D3DXConcatenateMeshes(meshs,2,D3DXMESH_MANAGED,TransM,0,NULL,TheD3DApp::Instance()->GetD3DDev(),&m_pMesh));
			AddTexture(t);
		}

	}
}

void Building::GenRoundedTri()
{
	HRESULT hr;

	bool tiered = COIN_FLIP;
	int roundedness = 3;
	
	int NumVerts= ((roundedness*3)+1)*2;	
	int NumFaces= ((roundedness*2)+3)*4;
	float lip = 0;
	if(tiered)
	{lip= (MY_RAND(4)+1)/50;}
	int lidSize= MY_RAND(m_Height/10)+1;
	int height = m_Height;

	if(tiered)
	{
		height=lidSize;
	}

	float StepA=m_vTriArea.AngleA/roundedness;
	float StepB=m_vTriArea.AngleB/roundedness;
	float StepC=m_vTriArea.AngleC/roundedness;

	D3DXCreateMesh(NumFaces,NumVerts,D3DXMESH_MANAGED,TheD3DApp::Instance()->GetVertexElements(),TheD3DApp::Instance()->GetD3DDev(),&m_pMesh);
	POSNORMUVVERTEX* pVertices;
	V(m_pMesh->LockVertexBuffer(0,(void**)&pVertices));
	WORD *IndexData=NULL;
	V(m_pMesh->LockIndexBuffer( 0, (void**)&IndexData ));

	int halfVerts=NumVerts/2;

	pVertices[0].Pos=D3DXVECTOR3(0,0,0);
	pVertices[0].Norm=D3DXVECTOR3(0,1,0);
	pVertices[0].UV=D3DXVECTOR2(0,0);

	pVertices[halfVerts].Pos=D3DXVECTOR3(0,height,0);
	pVertices[halfVerts].Norm=D3DXVECTOR3(0,1,0);
	pVertices[halfVerts].UV=D3DXVECTOR2(0,0);


	for (unsigned int i=1;i<roundedness+1;i++)
	{
		pVertices[i].Pos=m_vTriArea.a;
		pVertices[i].Pos.x-=sin((StepA*(i-2)))*D3DXVec3Length(&m_vTriArea.a);
		pVertices[i].Pos.z+=cos((StepA*(i-2)))*D3DXVec3Length(&m_vTriArea.a);
		pVertices[i].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i].UV=D3DXVECTOR2(0,0);

		pVertices[i+halfVerts].Pos=m_vTriArea.a;
		pVertices[i+halfVerts].Pos.x-=sin((StepA*(i-2)))*D3DXVec3Length(&m_vTriArea.a);
		pVertices[i+halfVerts].Pos.z+=cos((StepA*(i-2)))*D3DXVec3Length(&m_vTriArea.a);
		pVertices[i+halfVerts].Pos.y+=height;
		pVertices[i+halfVerts].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i+halfVerts].UV=D3DXVECTOR2(0,0);


		pVertices[i+roundedness].Pos=m_vTriArea.a;
		pVertices[i+roundedness].Pos.x-=sin((StepB*(i-2)))*D3DXVec3Length(&m_vTriArea.b);
		pVertices[i+roundedness].Pos.z+=cos((StepB*(i-2)))*D3DXVec3Length(&m_vTriArea.b);
		pVertices[i+roundedness].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i+roundedness].UV=D3DXVECTOR2(0,0);

		pVertices[i+roundedness+halfVerts].Pos=m_vTriArea.a;
		pVertices[i+roundedness+halfVerts].Pos.x-=sin((StepB*(i-2)))*D3DXVec3Length(&m_vTriArea.b);
		pVertices[i+roundedness+halfVerts].Pos.z+=cos((StepB*(i-2)))*D3DXVec3Length(&m_vTriArea.b);
		pVertices[i+roundedness+halfVerts].Pos.y+=height;
		pVertices[i+roundedness+halfVerts].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i+roundedness+halfVerts].UV=D3DXVECTOR2(0,0);


		pVertices[i+(roundedness*2)].Pos=m_vTriArea.a;
		pVertices[i+(roundedness*2)].Pos.x-=sin((StepC*(i-2)))*D3DXVec3Length(&m_vTriArea.c);
		pVertices[i+(roundedness*2)].Pos.z+=cos((StepC*(i-2)))*D3DXVec3Length(&m_vTriArea.c);
		pVertices[i+(roundedness*2)].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i+(roundedness*2)].UV=D3DXVECTOR2(0,0);

		pVertices[i+(roundedness*2)+halfVerts].Pos=m_vTriArea.a;
		pVertices[i+(roundedness*2)+halfVerts].Pos.x-=sin((StepC*(i-2)))*D3DXVec3Length(&m_vTriArea.c);
		pVertices[i+(roundedness*2)+halfVerts].Pos.z+=cos((StepC*(i-2)))*D3DXVec3Length(&m_vTriArea.c);
		pVertices[i+(roundedness*2)+halfVerts].Pos.y+=height;
		pVertices[i+(roundedness*2)+halfVerts].Norm=D3DXVECTOR3(0,1,0);
		pVertices[i+(roundedness*2)+halfVerts].UV=D3DXVECTOR2(0,0);
	}

	int indCount=0;
	for (unsigned int i=1;i<NumFaces;i+=4)
	{

		IndexData[indCount++]=0;
		IndexData[indCount++]=i;
		IndexData[indCount++]=i+1;


		IndexData[indCount++]=i;
		IndexData[indCount++]=i+1;
		IndexData[indCount++]=i+halfVerts;

		IndexData[indCount++]=i+1;
		IndexData[indCount++]=i+halfVerts;
		IndexData[indCount++]=i+halfVerts+1;


		IndexData[indCount++]=halfVerts;
		IndexData[indCount++]=i+halfVerts;
		IndexData[indCount++]=i+halfVerts+1;
	}
	V(m_pMesh->UnlockVertexBuffer());
	V(m_pMesh->UnlockIndexBuffer());
}